/*
 * Licensed to the http://code.google.com/p/crunchutils under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.crunchutils;

import java.util.Date;
import org.apache.commons.lang.time.DateUtils;
import org.joda.time.DateTime;
import org.joda.time.Period;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.PeriodFormatter;
import org.joda.time.format.PeriodFormatterBuilder;

/**
 * Utility methods to operate on date & time
 * @author James Selvakumar
 */
public class CrunchDateUtils
{
    /**
     * Parse the datetime from the given datetime string using the given pattern
     * @param dateTime The datetime string
     * @return The parsed date
     */
    public static Date parseDateTime(String dateTime, String datePattern)
    {
        return DateTimeFormat.forPattern(datePattern).parseDateTime(dateTime).toDate();
    }

    /**
     * Format the date object using the given date pattern
     * @param date The date object to be formatted
     * @return The formatted date string
     */
    public static String formatDateTime(Date date, String datePattern)
    {
        return DateTimeFormat.forPattern(datePattern).print(new DateTime(date));
    }

    /**
     * Returns a date object without time or to be precise rounding to start time of a day
     * @param date
     * @return
     */
    public static Date getDateWithoutTime(Date date)
    {
        String datePattern = "yyyy/MM/dd";
        String formattedDate = formatDateTime(date, datePattern);
        return parseDateTime(formattedDate, datePattern);
    }

    /**
     * Returns a date object with the time rounded to end time of day
     * @param date
     * @return
     */
    public static Date roundToEndTimeOfDay(Date date)
    {
        Date dateWithoutTime = getDateWithoutTime(date);
        Date roundedDate = DateUtils.addHours(dateWithoutTime, 23);
        roundedDate = DateUtils.addMinutes(roundedDate, 59);
        roundedDate = DateUtils.addSeconds(roundedDate, 59);
        return roundedDate;
    }

    /**
     * Returns a date object with the time rounded to start time of a day
     * @param dateTime
     * @return
     */
    public static Date roundToStartTimeOfDay(Date dateTime)
    {
        return getDateWithoutTime(dateTime);
    }

    /**
     * Returns the formatted elapsed time between the two given times starting from minutes
     * @param startTime
     * @param endTime
     * @return
     */
    public static String getElapsedTimeStartingFromMinutes(long startTime, long endTime)
    {
        Period period = new Period(startTime, endTime);
        PeriodFormatter formatter = new PeriodFormatterBuilder().appendMinutes().appendSuffix(" minute ", " minutes ").
                appendSeconds().appendSuffix(" second ", " seconds ").
                appendMillis().appendSuffix(" milliseconds ").toFormatter();
        return formatter.print(period).trim();
    }
}
